package br.com.foxinline.servico;

import br.com.foxinline.generico.ServicoGenerico;
import br.com.foxinline.modelo.Bairro;
import br.com.foxinline.modelo.Dne;
import br.com.foxinline.modelo.Endereco;
import br.com.foxinline.modelo.FaceQuadra;
import br.com.foxinline.modelo.Imovel;
import br.com.foxinline.modelo.Quadra;
import br.com.foxinline.modelo.Setor;
import java.beans.Transient;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.persistence.NoResultException;
import javax.persistence.Query;

/**
 *
 * @author laverson
 */
@Stateless
public class FaceQuadraServico extends ServicoGenerico<FaceQuadra> {

    @EJB
    SetorServico setorServico;
    @EJB
    DneServico dneServico;
    @EJB
    BairroServico bairroServico;
    @EJB
    QuadraServico quadraServico;
    @EJB
    CidadeServico cidadeServico;
    @EJB
    ImovelServico imovelServico;
    @EJB
    FaceQuadraServico faceQuadraServico;
    private Long quantidadeRegistrosResults;

    public FaceQuadraServico() {
        super(FaceQuadra.class);
    }

    @Override
    public void delete(FaceQuadra entity) {
        FaceQuadra entityToBeRemoved = getEntityManager().merge(entity);
        getEntityManager().remove(entityToBeRemoved);
    }

    @Override
    public List<FaceQuadra> find(FaceQuadra entidade, Integer first, Integer pageSize) {
        String select = "SELECT f ";
        String sql = "FROM " + FaceQuadra.class.getSimpleName() + " f ";
        String where = "WHERE ";
        String orderBy = "ORDER BY f.id asc";

        Quadra quadra = getQuadra(entidade);
        Setor setor = getSetor(entidade);
        Dne dne = getDne(entidade);
        Bairro bairro = getBairro(entidade);

        if (quadra != null) {
            sql += " JOIN f.quadra q ";
            where += "q.id = :quadraId AND ";
        }

        if (quadra == null && setor != null) {
            sql += " JOIN f.quadra q JOIN q.setor s ";
            where += "s.id = :setorId AND ";
        }

        if (dne != null) {
            sql += "JOIN f.dne d ";
            where += "d.id = :dneId AND ";
        }

        if (bairro != null) {
            sql += "JOIN f.dne d JOIN d.bairro b ";
            where += "b.id = :bairroId AND ";
        }

        where += "1=1 ";

        Query query = getEntityManager().createQuery(select.concat(sql).concat(where).concat(orderBy));

        setQuantidadeRegistros(sql.concat(where), entidade, query);

        setParameters(entidade, query);

        if (first != null && pageSize != null) {
            query.setFirstResult(first).setMaxResults(pageSize);
        }

        return query.getResultList();
    }

    @Transient
    private void setParameters(FaceQuadra entidade, Query query) {
        Quadra quadra = getQuadra(entidade);
        Setor setor = getSetor(entidade);
        Dne dne = getDne(entidade);
        Bairro bairro = getBairro(entidade);

        if (quadra != null) {
            query.setParameter("quadraId", quadra.getId());
        }

        if (quadra == null && setor != null) {
            query.setParameter("setorId", setor.getId());
        }

        if (dne != null) {
            query.setParameter("dneId", dne.getId());
        }

        if (bairro != null) {
            query.setParameter("bairroId", bairro.getId());
        }
    }

    private void setQuantidadeRegistros(String sql, FaceQuadra entidade, Query query) {

        String select = "SELECT count(f) ";

        query = getEntityManager().createQuery(select + sql);

        setParameters(entidade, query);

        quantidadeRegistrosResults = (Long) query.getSingleResult();
    }

    @Override
    public Long quantidadeRegistros() {
        return quantidadeRegistrosResults;
    }

    private Setor getSetor(FaceQuadra entidade) {

        if (entidade.getQuadra() != null) {

            Quadra quadra = entidade.getQuadra();

            if (quadra.getSetor() != null && quadra.getSetor().getId() != null) {
                return quadra.getSetor();
            }
        }

        return null;
    }

    private Quadra getQuadra(FaceQuadra entidade) {

        if (entidade.getQuadra() != null && entidade.getQuadra().getId() != null) {
            return entidade.getQuadra();
        }

        return null;
    }

    private Dne getDne(FaceQuadra entidade) {

        if (entidade.getDne() != null && entidade.getDne().getId() != null) {
            return entidade.getDne();
        }

        return null;
    }

    private Bairro getBairro(FaceQuadra entidade) {

        if (entidade.getDne() != null && entidade.getDne().getId() == null) {

            Dne dne = entidade.getDne();

            if (dne.getBairro() != null && dne.getBairro().getId() != null) {
                return dne.getBairro();
            }
        }

        return null;
    }

    public List<Bairro> autocompleteBairroSetorQuadra(Long setor, Long quadra, String bairro) {
        String sql = "select distinct b from " + FaceQuadra.class.getSimpleName()
                + " f join f.dne.bairro b"
                + " where f.setorNumero = :setor"
                + " and f.quadraNumero = :quadra";
        if (bairro != null && !bairro.isEmpty()) {
            sql += " and lower(b.nome) like lower(:bairro)";
        }

        Query q = getEntityManager().createQuery(sql);
        q.setParameter("setor", setor);
        q.setParameter("quadra", quadra);
        if (bairro != null && !bairro.isEmpty()) {
            q.setParameter("bairro", "%" + bairro + "%");
        }

        return q.getResultList();
    }

    public List<FaceQuadra> autocompleteFaceQuadraBairroSetorQuadra(Long setor, Long quadra, Bairro bairro, String logradouro) {
        String sql = "select f from " + FaceQuadra.class.getSimpleName()
                + " f where f.setorNumero = :setor"
                + " and f.quadraNumero = :quadra"
                + " and f.dne.bairro = :bairro";
        if (logradouro != null && !logradouro.isEmpty()) {
            sql += " and lower(f.dne.rua) like lower(:logradouro)";
        }


        Query q = getEntityManager().createQuery(sql);
        q.setParameter("setor", setor);
        q.setParameter("quadra", quadra);
        q.setParameter("bairro", bairro);
        if (logradouro != null && !logradouro.isEmpty()) {
            q.setParameter("logradouro", "%" + logradouro + "%");
        }

        return q.getResultList();
    }

    public void atualizarFaceQuadra() {
        String sql = "select distinct f from " + FaceQuadra.class.getSimpleName() + " f where f.setorNumero = 5";
        Query query = getEntityManager().createQuery(sql);

        List<FaceQuadra> result = query.getResultList();

        Quadra quadra;

        for (FaceQuadra face : result) {
            sql = "select q from " + Quadra.class.getSimpleName() + " q JOIN q.setor s "
                    + "where q.numero = " + face.getQuadraNumero() + " and s.numero = " + face.getSetorNumero() + " group by q";

            query = getEntityManager().createQuery(sql);

            List<Quadra> quadras = query.getResultList();

            for (Quadra q : quadras) {
                System.err.println("quadra = " + q);
            }

            try {

                quadra = (Quadra) query.getSingleResult();
                face.setQuadra(quadra);
                update(face);

            } catch (NoResultException e) {
                System.err.println("Nenhum resultado: " + sql);
            }
        }
    }

    public BigDecimal valorFaceQuadraManual(Imovel imovel) {

        if(imovel.getInscricaoCadastralS() == null){
            return null;
        }

        if (imovel.getInscricaoCadastralS() == 5) {

            if (imovel.getInscricaoCadastralQuadra() != null && imovel.getInscricaoCadastralQuadra() != 0) {
                if (imovel.getInscricaoCadastralQuadra() == 97 && imovel.getEnderecoImovel() != null
                        && imovel.getEnderecoImovel().getLogradouro().contains("rua dr. oscar clark")) {
                    return new BigDecimal("122.05");
                } else if (imovel.getInscricaoCadastralQuadra() == 97) {
                    return new BigDecimal("76.38");
                }

                // 74,80
                List<Integer> a = Arrays.asList(new Integer[]{18, 19, 29, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
                            56, 57, 58, 59, 60, 61, 62, 63, 156, 157, 158, 173, 174, 175, 189, 190, 191, 192, 193});

                if (a.contains(imovel.getInscricaoCadastralQuadra())) {
                    return new BigDecimal("74.80");
                }

                // 76,38
                List<Integer> b = Arrays.asList(new Integer[]{64, 65, 66, 77, 78, 79, 80, 95, 96, 100, 101, 111, 112});
                if (b.contains(imovel.getInscricaoCadastralQuadra())) {
                    return new BigDecimal("76.38");
                }


                //122,05
                List<Integer> c = Arrays.asList(new Integer[]{67, 68, 69, 81, 82, 83, 98});

                if (c.contains(imovel.getInscricaoCadastralQuadra())) {
                    return new BigDecimal("122.05");
                }

                //114,57
                List<Integer> d = Arrays.asList(new Integer[]{70, 71, 72, 73, 74, 75, 84, 85, 86, 87, 88, 89, 102, 103,
                            104, 105, 106, 107, 113, 114, 115, 117, 119, 120, 138, 139, 140, 141,
                            142, 143, 144, 145, 146, 147, 148, 159, 160, 161, 162, 163, 164, 165,
                            176, 177, 178, 179, 180, 181, 182});

                if (d.contains(imovel.getInscricaoCadastralQuadra())) {
                    return new BigDecimal("114.57");
                }

                //163,78
                List<Integer> e = Arrays.asList(new Integer[]{108, 109, 110, 121});
                if (e.contains(imovel.getInscricaoCadastralQuadra())) {
                    return new BigDecimal("163.78");
                }

                return new BigDecimal("27.56");

            }
        } else if (imovel.getInscricaoCadastralS() == 3) {
            List<Integer> a3 = Arrays.asList(new Integer[]{94, 96, 99, 110, 113, 116, 117, 135});

            // 31,50
            if (a3.contains(imovel.getInscricaoCadastralQuadra())) {
                return new BigDecimal("31.50");
            }
        }else if (imovel.getInscricaoCadastralS() == 6) {

            // 16,54
            if (imovel.getInscricaoCadastralQuadra() == 135) {
                return new BigDecimal("16.54");
            }

            // 17.32
            if (imovel.getInscricaoCadastralQuadra() == 480) {
                return new BigDecimal("17.32");
            }

            // 18.50
            if (imovel.getInscricaoCadastralQuadra() == 34 || imovel.getInscricaoCadastralQuadra() == 36) {
                return new BigDecimal("18.50");
            }

            // 21.65
            if (imovel.getInscricaoCadastralQuadra() == 183 ||
                    imovel.getInscricaoCadastralQuadra() == 185 ||
                    imovel.getInscricaoCadastralQuadra() == 199) {
                return new BigDecimal("21.65");
            }

            // 38.19
            if (imovel.getInscricaoCadastralQuadra() == 488 && imovel.getEnderecoImovel() != null &&
                    imovel.getEnderecoImovel().getLogradouro().equalsIgnoreCase("Rua Itaúna")) {
                return new BigDecimal("53.94");
            }else if (imovel.getInscricaoCadastralQuadra() == 488){
                return new BigDecimal("38.19");
            }

            List<Integer> a6 = Arrays.asList(new Integer[]{164,165,166,170,171,172,173,186,187,193,194,195,197,200,201,211});
            //43.31
            if (a6.contains(imovel.getInscricaoCadastralQuadra())) {
                return new BigDecimal("43.31");
            }

            List<Integer> b6 = Arrays.asList(new Integer[]{9,10,11,12,13,46,47,48,50,52,53,54,55});
            //55.12
            if (b6.contains(imovel.getInscricaoCadastralQuadra())) {
                return new BigDecimal("55.12");
            }

            List<Integer> c6 = Arrays.asList(new Integer[]{7,8,44,45});
            //59.06
            if (c6.contains(imovel.getInscricaoCadastralQuadra())) {
                return new BigDecimal("59.06");
            }

            // 62.99
            if (imovel.getInscricaoCadastralQuadra() == 152) {
                return new BigDecimal("62.99");
            }

            // 69.99
            if (imovel.getInscricaoCadastralQuadra() == 14) {
                return new BigDecimal("69.99");
            }


        }
        /**
         * SETOR 6
         *
         * R$ 16,54
            (135 )

            R$ 17,32
            (480 )

            R$ 18,50
            (34,36)

            R$ 21,65
            (183,185,199)

            R$ 38,19
            (488)

            R$ 43,31
            (164,165,166,170,171,172,173,186,187,193,194,195,197,200,201,211)

            R$ 53,94
            ( 488 - Rua itaúna )

            R$ 55,12
            (9,10,11,12,13,46,47,48,50,52,53,54,55 )

            R$ 59,06
            (7,8,44,45 )

            R$ 62,99
            (152)

            R$ 69,69
            (14 )
         */
        
        /**
         * SETOR 1
            7 - RUA AFONSO PENA = 106,30
            7 - RUA JOSE BONIFACIO = 90,55
            7 - RUA PRUDENTE DE MORAIS = 90,55
            7 - RUA TABAJARA = 14,17

            10 - RUA AFONSO PENA = 106,30
            10 - RUA AIMORES = 80,31
            10 - RUA PRUDENTE DE MORAIS = 80,31
            10 - RUA XAVANTES = 70,87

            11 - RUA AFONSO PENA = 94,49
            11 - RUA PRUDENTE DE MORAIS = 70,87
            11 - RUA TREMEMBES = 70,87
            11 - RUA XAVANTES = 70,87

            12 - RUA AFONSO PENA = 94,49
            12 - RUA PRUDENTE DE MORAIS = 70,87
            12 - RUA TAMOIOS = 70,87
            12 - RUA TREMEMBES = 70,87

            36 - RUA MELVIN JONES = 70,87
            36 - RUA PRUDENTE DE MORAIS = 70,87
            36 - RUA SAMUEL SANTOS = 78,74
            36 - RUA SANTA CECILIA = 70,87

            52 - RUA CAIAPOS = 70,87
            52 - RUA GUAPORE = 70,87
            52 - RUA SAMUEL SANTOS = 90,55
            52 - RUA TIMBIRA = 70,87

            152 - RUA ANISIO NEVES = 61,42
            152 - RUA BENEDICTO DOS S LIMA = 61,42
            152 - RUA OSWALDO CRUZ = 93,70

         *
         */

        /**
         * SETOR 3
         *
         * --31,50 (94, 96, 99, 110, 113, 116, 117, 135)
         */
        /**
         * setor 5 -- 74,80 (18,19,29, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
         * 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 156, 157, 158, 173, 174, 175,
         * 189, 190, 191, 192, 193)
         *
         * -- 76,38 (64, 65, 66, 77, 78, 79, 80, 95, 96, 97(*), 100, 101, 111,
         * 112, )
         *
         * -- 122,05 (67, 68, 69, 81, 82, 83, 98, 97(rua dr. oscar clark))
         *
         * -- 114,57 (70, 71, 72, 73, 74, 75, 84, 85, 86, 87, 88, 89, 102, 103,
         * 104, 105, 106, 107, 113, 114, 115, 117, 119, 120, 138, 139, 140, 141,
         * 142, 143, 144, 145, 146, 147, 148, 159, 160, 161, 162, 163, 164, 165,
         * 176, 177, 178, 179, 180, 181, 182, )
         *
         * -- 163,78 (108, 109, 110, 121, )
         */
        return null;
    }

    public BigDecimal valorFaceQuadra(Imovel imovel) {

        //id, valorufmp, quadra_id, dne_id, setornumero, quadranumero

        Endereco endereco = imovel.getEnderecoImovel();

        if (endereco != null //                && (endereco.getLogradouro() != null && !endereco.getLogradouro().isEmpty())
                //                && (endereco.getBairro() != null && !endereco.getBairro().isEmpty())
                //                && (endereco.getBairroDne() != null && endereco.getBairroDne().getNome() != null && !endereco.getBairroDne().getNome().isEmpty())
                //                && (endereco.getLogradouro() != null && !endereco.getLogradouro().isEmpty())
                ) {

            Dne dne = new Dne();

            if (endereco.getCep() != null && !endereco.getCep().isEmpty()) {

                dne.setCep(endereco.getCep());

            } else {

                if (endereco.getBairroDne() != null) {

                    dne.setBairro(endereco.getBairroDne());

                } else if (endereco.getBairro() != null && !endereco.getBairro().isEmpty()) {

                    List<Bairro> bairros = bairroServico.autocomplete(endereco.getBairro());

                    if (!bairros.isEmpty()) {
                        Bairro b = bairros.get(0);
                        dne.setBairro(b);
                    }
                }

                dne.setRua(endereco.getLogradouro());
                dne.setCidade(cidadeServico.find(5658L));
            }

            List<Dne> dnes = dneServico.find(dne, null, null);

            if (dnes != null && !dnes.isEmpty()) {
                dne = dnes.get(0);
            }

            FaceQuadra faceQuadra = new FaceQuadra();
            Quadra quadra = new Quadra();
            Setor setor = new Setor();

            setor.setNumero(imovel.getInscricaoCadastralS());
            List<Setor> setores = setorServico.find(setor, null, null);

            if (setores != null && !setores.isEmpty()) {
                setor = setores.get(0);
            }

            quadra.setSetor(setor);

            quadra.setNumero(imovel.getInscricaoCadastralQuadra());

            List<Quadra> quadras = quadraServico.find(quadra, null, null);

            if (quadras != null && !quadras.isEmpty()) {
                quadra = quadras.get(0);
            }


            faceQuadra.setDne(dne);
            faceQuadra.setQuadra(quadra);

            List<FaceQuadra> faces = find(faceQuadra, null, null);

            if (faces != null && !faces.isEmpty()) {
                return faces.get(0).getValorUfmp();
            }

        }

        return null;
    }
}
